using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Text.RegularExpressions;
using System.IO;

namespace Lizk.Media
{
    public class VideoData
    {
        public string volume = "", path = "", mimetype = "", crc = "", encoder = "", title = "", show = "", creator = "", description = "", comment = "", genre = "", type = "", source = "", format = "", artwork = "";
        public long filesize = 0, lastmodified = Int64.MaxValue;
        public int duration = 0, episode = 0, total_episodes = 0, season = 0, lastepisode = 0;

        public static void ParseAnimeFilename(VideoData video, string file)
        {
            string crc = "", ver = "0", grp = "", ep = "", tail = "", head = ""; ;

            Regex crcPattern = new Regex("(?i)([^A-Z0-9]([A-Z0-9]{8})[^A-Z0-9])");
            Regex crcPattern2 = new Regex(@"(?i)(\(|\[)([A-Z0-9]{8})(\)|\])");
            Regex crcCheckPattern = new Regex("[0-9]+");

            Regex grpStartPattern = new Regex(@"^(\(|\[)([^\(\[\]\)]+)(\)|\]).*?");
            Regex grpEndPattern = new Regex(@".*?(\(|\[)([^\(\[\]\)]+)(\)|\])$");

            Regex boxedPattern = new Regex(@".*?(\(|\[)([^\(\[\]\)]+)(\)|\]).*?");

            Regex versionPattern = new Regex("(?i).*?[^A-Z](v[0-9])([^A-Z0-9]|$).*?");

            Regex[] episodePattern = new Regex[7];
            episodePattern[0] = new Regex(@"(?i)(.*?)(\W|^)(\d{1,3}-\d{1,3})(\W|$)(.*?)");
            episodePattern[1] = new Regex(@"(?i)(.*?)(\W|^)(\d{1,3}\s*&\s*\d{1,3})(\W|$)(.*?)");
            episodePattern[2] = new Regex(@"(?i)(.*?)(\W|^)(ep\s*(\d{1,3}))(\W|$)(.*?)");
            episodePattern[3] = new Regex(@"(?i)(.*?)(\W|^)(episode\s*(\d{1,3}))(\W|$)(.*?)");
            episodePattern[4] = new Regex(@"(?i)(.*?)(\W|^)(ep[A-Z]*\s*(\d{1,3}))(\W|$)(.*?)");
            episodePattern[5] = new Regex(@"(.*?)(\W|^)(\d{1,3})(\W\D+$|$)");
            episodePattern[6] = new Regex(@"(.*?)(\W|^)(\d{1,3})(\W|$)(.*?)");

            Regex episodeNumberPattern = new Regex(@"^.*?(\d+).*?$");

            string name = Path.GetFileNameWithoutExtension(file);
            Match m;

            if ((m = crcPattern2.Match(name)).Success)
            {

                while (!crcCheckPattern.IsMatch(m.Groups[2].ToString()) && (m = m.NextMatch()).Success) { }

                if (m.Success)
                {
                    name = name.Replace(m.Groups[1].ToString() + m.Groups[2].ToString() + m.Groups[3].ToString(), "");
                    crc = m.Groups[2].ToString();
                }
            }
            if (crc.Length == 0 && (m = crcPattern.Match(name)).Success)
            {
                while (!crcCheckPattern.IsMatch(m.Groups[2].ToString()) && (m = m.NextMatch()).Success) { }

                if (m.Success)
                {
                    name = name.Replace(m.Groups[1].ToString(), "");
                    crc = m.Groups[2].ToString();
                }
            }

            if ((m = grpStartPattern.Match(name)).Success)
            {
                name = name.Replace(m.Groups[1].ToString() + m.Groups[2].ToString() + m.Groups[3].ToString(), "");
                grp = m.Groups[2].ToString();
            }
            else
            {
                if ((m = grpEndPattern.Match(name)).Success)
                {
                    name = name.Replace(m.Groups[1].ToString() + m.Groups[2].ToString() + m.Groups[3].ToString(), "").Trim();
                    grp = m.Groups[2].ToString();
                }
            }

            name = name.Replace(".", " ").Replace("_", " ").Trim();
            Regex.Replace(name, @"\s{2,}", " ");

            if ((m = versionPattern.Match(name)).Success)
            {
                name = name.Replace(m.Groups[1].ToString(), "");
                ver = m.Groups[1].ToString().Substring(1);
            }



            List<string> more = new List<string>();
            while ((m = boxedPattern.Match(name)).Success)
            {
                name = name.Replace(m.Groups[1].ToString() + m.Groups[2].ToString() + m.Groups[3].ToString(), "");
                more.Add(m.Groups[2].ToString());
            }



            for (int j = 0; j < episodePattern.Length; j++)
            {
                if ((m = episodePattern[j].Match(name)).Success)
                {
                    head = Regex.Replace(Regex.Replace(m.Groups[1].ToString(), @"(?i)[^A-Z0-9 !~\+-=']+", ""), @"\s+[^\w]+$", "").Trim();
                    switch (j)
                    {
                        case 0:
                        case 1:
                        case 6:
                            name = name.Replace(m.Groups[2].ToString() + m.Groups[3].ToString() + m.Groups[4].ToString(), "");
                            tail = m.Groups[5].ToString();
                            if (j < 2)
                            {
                                List<string> al = new List<string>();
                                ep = m.Groups[3].ToString();
                                while ((m = episodeNumberPattern.Match(ep)).Success)
                                {
                                    al.Add(m.Groups[1].ToString());
                                    ep = ep.Replace(m.Groups[1].ToString(), "");
                                }
                                ep = "";
                                for (int i = 0; i < al.Count; i++)
                                {
                                    if (i != 0)
                                        ep += "-";
                                    ep += al[i];
                                }
                            }
                            else
                            {
                                ep = m.Groups[3].ToString();
                            }
                            break;
                        case 5:
                            name = name.Replace(m.Groups[2].ToString() + m.Groups[3].ToString() + m.Groups[4].ToString(), "");
                            ep = m.Groups[3].ToString();
                            tail = m.Groups[4].ToString();
                            break;
                        case 2:
                        case 3:
                        case 4:
                            name = name.Replace(m.Groups[2].ToString() + m.Groups[3].ToString() + m.Groups[5].ToString(), "");
                            tail = m.Groups[6].ToString();
                            ep = m.Groups[4].ToString();
                            m = episodeNumberPattern.Match(ep);
                            ep = m.Groups[1].ToString();
                            break;

                    }
                    break;
                }
            }
            //            int version = ver.Length > 0 ? Int32.Parse(ver) : 1;
            //            tail = tail.Trim().Length > 0 ? Regex.Replace(tail, @"\W", " ").Trim() : "";

            video.title = head != "" ? head : Regex.Replace(Regex.Replace(Regex.Replace(name, @"(?i)[^A-Z0-9 !~\+-=]+", ""), @"\s{2,}", " "), @"\s+[^\w]+$", "").Trim();
            video.encoder = grp;
            video.crc = crc;
            video.comment = String.Join(", ", more.ToArray());
            if (Regex.IsMatch(ep, @"\d{1,3}-\d{1,3}"))
            {
                string[] h = ep.Split(new char[] { '-' });
                video.episode = Int32.Parse(h[0]);
                video.lastepisode = Int32.Parse(h[1]);
            }
            else if (ep != "")
            {
                video.episode = Int32.Parse(ep);
                video.lastepisode = video.episode;
            }
        }
        public static void ParseTVShowFilename(VideoData video, string file)
        {
            Regex[] patnr = {
                new Regex(@"(?i)(?:^.*?[^a-z0-9]|^)s?(\d{1,2})[a-z]+(\d{1,2})[\-_. ](?:ep|[a-z])?(\d{1,2})((?:[^a-z0-9].*?|\.)\w{3,})$"),
                new Regex(@"(?i)(?:^.*?[^a-z0-9]|^)s?(\d{1,2})[a-z]+(\d{1,2})((?:[^a-z0-9].*?|\.)\w{3,})$"),
                new Regex(@"(?i)(?:^.*?[^a-z0-9]|^)(\d{3})((?:[^a-z0-9](\D)*?|\.)\w{3,})$"),
                new Regex(@"(?i)(?:^.*?[^a-z0-9]|^)(\d{3})((?:[^a-z0-9].*?|\.)\w{3,})$"),
                new Regex(@"(?i)(?:^.*?[^a-z0-9]|^)s?(\d{1,2})[^a-z0-9].*?(?:e|d|ep)(\d{1,2})((?:[^a-z0-9].*?|\.)\w{3,})$"),
                new Regex(@"(?i)(?:^.*?[^a-z0-9]|^)[a-z]+(\d{1,2})((?:[^a-z0-9].*?|\.)\w{3,})$")
                            };
            for (int i = 0; i < patnr.Length; i++)
            {
                Match m = patnr[i].Match(Path.GetFileName(file));
                if (m.Success)
                {
                    switch (i)
                    {
                        case 0:
                            video.season = Int32.Parse(m.Groups[1].Value);
                            video.episode = Int32.Parse(m.Groups[2].Value);
                            video.lastepisode = Int32.Parse(m.Groups[3].Value);
                            if (video.lastepisode < video.episode)
                                video.lastepisode = video.episode;
                            video.comment = Path.GetFileNameWithoutExtension(m.Groups[4].ToString());
                            break;
                        case 1:
                        case 4:
                            video.season = Int32.Parse(m.Groups[1].Value);
                            video.lastepisode = video.episode = Int32.Parse(m.Groups[2].Value);
                            video.comment = Path.GetFileNameWithoutExtension(m.Groups[3].ToString());
                            break;
                        case 2:
                        case 3:
                            video.season = Int32.Parse(m.Groups[1].Value.Substring(0, 1));
                            video.lastepisode = video.episode = Int32.Parse(m.Groups[1].Value.Substring(1, 2));
                            video.comment = Path.GetFileNameWithoutExtension(m.Groups[2].ToString());
                            break;
                        case 5:
                            video.season = 0;
                            video.lastepisode = video.episode = Int32.Parse(m.Groups[1].Value);
                            video.comment = Path.GetFileNameWithoutExtension(m.Groups[2].ToString());
                            break;
                    }
                    return;
                }
            }
        }


        public object[] DataRowObject
        {
            get { return new object[] { this.volume, this.path, this.filesize, this.mimetype, this.crc, this.encoder, this.format, this.duration, this.title, this.episode, this.lastepisode, this.total_episodes, this.season, this.show, this.creator, this.description, this.comment, this.genre, this.type, this.source, this.artwork, this.lastmodified }; }
        }


    }
}
